iT邦幫忙

2026 iThome 鐵人賽

DAY 1
1
Build on Google AI

LOCAL:30 天打造 LINE × Google AI 地方服務 Agent系列 第 1

Day 1|LOCAL:把地方服務需求變成 LINE × Google AI 的工程規格

  • 分享至 

  • xImage
  •  

接下來三十天,我要以彰化作為示範情境,逐步打造 LOCAL:一套以 LINE 為入口、Google AI 為智慧核心的地方服務 Agent。第一天先不急著串 API,而是定義使用者、系統責任、實作邊界與驗收標準。我們要留下的,不只是會回答問題的展示,而是別人能理解、執行、測試與延伸的開源作品。

LOCAL is a planned open-source project that brings Google AI into LINE-based local services. Using Changhua as a reference setting, this thirty-day series will explore tool use, structured outputs, conversational state, consented memory, evaluation, and cloud deployment. Day 1 defines the intended users, system boundaries, and acceptance criteria before implementation. The goal is not a chatbot that merely sounds helpful, but a system whose actions and limitations can be inspected, tested, and reproduced. The examples in this article are design specifications, not completed experiments.

https://ithelp.ithome.com.tw/upload/images/20260915/20120682XgU9lUYAXS.png
圖1:LOCAL 的責任邊界(設計示意):模型提出工具請求,後端驗證權限、執行並確認實際狀態;工具結果回到 Agent/編排層,再決定後續處理。最終由程式驗證回覆資料並組裝 LINE 訊息。

前言:一句「已經幫您處理」,到底算不算完成?

假設有人在 LINE 裡詢問:

「這個星期六想帶長輩去彰化走走,希望少走路、吃素,有沒有適合的活動?不確定的地方,可以幫我問服務人員嗎?」

這是為本系列設計的情境,不是某位客戶的真實對話。

要產生一段親切的推薦文字,不難想像。但如果推薦的活動已經結束、無障礙資訊沒有來源,或者系統回了一句「已經通知服務人員」,後端卻根本沒有留下請求,那段文字再流暢,也沒有完成服務。

我想做的,不是讓 LINE Bot 更會說話,而是讓它更有能力把事情處理好。

我是陳佳新,大家習慣叫我佳新哥。我在彰化經營奇步應用,也是 LINE API Expert 與 GDG Changhua Organizer。我的工作經常圍繞 LINE、網站、活動與地方服務:入口要好用,資料要正確,流程也必須有辦法收尾。

因此,這次鐵人賽,我想把自己的 LINE 開發經驗與 Google AI 的能力放進同一件作品。

它叫做 LOCAL

三十天後,我希望留下的不只是三十篇文章,而是一套別的開發者可以接手研究、跑起來、檢查結果,再換成自己場域資料的開源專案。

一、為什麼是 LOCAL:從會回答,走向能完成服務

我的出發點是這句話:

LINE 是入口 → Google AI 是智慧能力 → 地方政府、中小企業與社群是落地現場。

選擇 LINE,不是因為 Agent 只能長在 LINE 裡,而是我想從自己熟悉的入口出發,減少這次必須同時解決的問題。先把一段服務做好,比同時開發新 App、新後台和新 Agent 更重要。

彰化也不是功能限制,而是第一個示範場域。我會以能公開使用的資料或明確標示的合成資料建立範例,不直接搬出客戶程式、正式個資或未經授權的素材。未來能不能換成另一個地方,會是這套設計必須接受的檢查。

這個系列首先寫給已有 Web、HTTP API 或 LINE Bot 基礎,想往 Google AI 應用開發前進的工程師。

你不需要先精通 Agent,但應該願意讀程式、執行測試,也願意問:「為什麼不能用更簡單的方式?」

因為不是每個問題都需要 Agent。

固定的營業資訊、明確的表單流程,可能用查詢與條件判斷就能做得很好。傳統 LINE Bot 也能呼叫 API、操作資料庫;我不會把「能查資料」說成 Agent 才有的能力。

LOCAL 要探索的是:當使用者的說法不同、條件尚未完整、下一步必須依查詢結果決定時,能否讓模型在受控範圍內選擇工具、觀察結果,再決定追問、回覆或交給真人。

Gemini 的 Function Calling 提供了這種連接方式:模型可以提出函式名稱與參數,但實際執行仍由應用程式負責。[1]

這也決定了本系列的一條底線:

模型可以建議下一步,權限與完成判定不能只靠模型說了算。

同樣地,長期記憶不是一張「這就是 Agent」的認證。有沒有記憶,應該由任務需求決定。LOCAL 會研究它,但不會為了讓系統看起來更聰明,就把每一句對話永久留下。

如果一定要用一句容易記住的話介紹 LOCAL,我會說:

會查、會做、會記,也會說不知道。

這是產品方向,不是今天已經達成的功能清單。接下來要做的,就是把這幾個字變成能被檢查的規格。

這裡的 LOCAL 是品牌名,統一大寫、不加句點,呼應我們想服務的地方。五個字母仍保留為設計地圖,提醒我不能只顧著模型回答,卻忘了入口、工具、狀態、責任與交付。

字母 設計面向 在 LOCAL 裡關心什麼
L LINE-native Interface LINE 服務入口與訊息體驗
O Orchestration & Tools Agent 編排、工具契約與受控執行
C Context & Consented Memory 上下文、任務狀態與經同意的記憶
A Assurance & Accountability 品質驗證、權限、人工接管與責任
L Launch & Learning Loop 部署、觀測、評測與持續改善

這五個面向不是五個獨立產品,也不是每次請求都必須依序經過的五個步驟。它們是本專案的設計約定,不是 Google 官方標準;後續選擇技術時,要回到它解決的問題,而不是為了湊字母堆功能。

二、三十天要做出什麼:先畫責任邊界,再寫程式

我預計完成一套以單一 Agent 為主的地方服務開源套件。它會接收 LINE 訊息、使用 Gemini 理解需求,並在後端控制下存取地方資料與服務工具。

第一版先聚焦三項工具,下面的名稱是 LOCAL 預定的應用程式介面,不是 Google 或 LINE 的官方 API:

工具 預定工作 必須守住的邊界
search_local_places 查詢地方資訊、景點與適用條件 只依資料回覆,保留來源與更新時間
search_local_events 按日期、地區與條件查詢活動 沒有資料就說明,不能自行編造活動
create_handoff_request 經使用者確認後建立人工服務請求 必須取得後端結果;建立請求不等於真人已接手

這三項工具對應三種不同責任:提供資訊、查詢時效性資料,以及產生需要追蹤的系統狀態。

前兩項先採唯讀設計。第三項會改變系統狀態,所以必須處理確認、重複執行與完成驗證,而不是多加一段 Prompt 就算結束。

整體流程先用一條線表示:

LINE 訊息 → Webhook 驗證與事件處理 → Gemini/Agent 判斷 → 後端驗證並執行工具 → 觀察結果 → 回覆或繼續處理

這不是只能走一次的流水線。工具回傳資料不足時,Agent 可能需要追問;工具發生錯誤時,也不能假裝整段流程已經成功。

Google 技術在這裡各有自己的位置。Google AI Studio 用來測試提示與模型行為,再把可行的原型移到 Gemini API。[2] 我預計使用 Google ADK 整理 Agent、工具與對話狀態;ADK 的文件也區分 Session、State 與跨對話的 Memory。[3]

Google Antigravity 則是協助建造 LOCAL 的開發工具,用於規格、程式與驗證工作,不是民眾實際使用的地方服務 Agent。[4] 雲端部署會以 Cloud Run 等實際可行的路徑驗證;ADK 官方已有 Cloud Run 部署文件,但實際採用的組合,仍要用執行結果和成本來決定。[5]

我不會為了在架構圖上放更多產品,就把所有元件都列為三十天必做。

模型、SDK、框架版本與資料儲存方案,會在相關實作篇記錄;尚未跑通的服務,不會先寫成已經整合完成。

另外,LOCAL 會把「生成內容」與「呈現畫面」分開。模型先輸出受約束的資料,程式再驗證並轉成固定的 LINE Flex Message 模板。Structured Output 能約束 JSON 結構,但結構合法不等於內容正確,應用程式仍須檢查欄位值與業務規則。[6]

換句話說,我不打算讓模型每次自由拼出整份畫面,也不會因為 JSON 可以解析,就相信裡面的活動真的存在。

今天先交付一份驗收案例。

回到開頭的服務情境:使用者已同意建立人工服務請求,但工具呼叫逾時了。這時 LOCAL 能不能回覆「已經幫您通知」?

我會先把期望寫成下面的 JSON。這是本系列自訂的合成驗收規格,不是 Gemini 的請求格式、LINE Webhook,也不是已執行的測試結果。

{
  "case_id": "handoff-timeout-001",
  "kind": "synthetic_acceptance_spec",
  "given": {
    "user_confirmed": true,
    "idempotency_key": "demo-request-001",
    "tool_result": { "status": "timeout" },
    "stored_request": "unknown"
  },
  "expected": {
    "reply_state": "pending_verification",
    "claim_completed": false,
    "next_step": "reconcile_by_idempotency_key",
    "retry_policy": "reuse_same_idempotency_key"
  }
}

stored_requestunknown,因為逾時只表示這一端沒有及時拿到結果,不能直接證明另一端完全沒做事。因此,系統不能宣告完成,也不該立刻用另一個識別值重建一次。

idempotency_key 是同一個服務請求的去重識別值。後續實作要在後端確保相同請求不會重複產生副作用,並用它核對既有紀錄;光有這個欄位,還不等於已經做到了冪等性。

這也呼應 LINE Webhook 的實際需求:同一事件可能被重複傳送,官方文件建議以 webhookEventId 偵測重複事件。[7] LOCAL 需要把事件接收與業務操作兩層都處理清楚,而不是把重送當成新的使用者要求。

這份規格今天還不會替任何人建立服務單,但它已經替後續程式立下一個可驗證的要求:

AI 回答「完成」,不等於後端真的完成。

至於第一版刻意不做的事情,也先說清楚:不做全能地方政府助手、不做多 Agent 大軍、不直接開放付款退款或任意資料異動,也不把教學作品宣稱為已符合所有正式服務需求的成品。

我寧可先把一段受控的服務流程做完整,再討論擴張。

三、這三十天怎麼走:每增加一項能力,就增加一份證據

LOCAL 不會是三十個各自獨立的小玩具,也不是每天輪流介紹一個 Google 產品。

我會先跑通一條最小流程,再讓前一版暴露出的問題,推動下一版的設計。

階段 要解決的問題 預計留下的成果
Day 1–6:定義與起步 到底要服務誰?純模型回答有哪些不足? 需求、範圍、20 題初始評測,以及 LINE → Gemini → LINE 的最小流程
Day 7–12:工具與資料 回答不能只靠猜,工具又如何被正確使用? 提示版本、結構化輸出、工具契約與地方查詢工具
Day 13–18:編排與對話 如何延續任務?什麼應該記,什麼不該記? ADK 整合、Session/State、記憶政策與既有系統串接範例
Day 19–24:驗證與責任 Agent 是否做對?不該做的事能否被攔住? 評測資料集、對照實驗、權限測試與人工接管流程
Day 25–30:部署與交付 換環境、換資料、換一個人操作,還能不能跑? 可靠性驗證、雲端部署、移植範例、重現紀錄與版本發布

上表是寫作順序,不是安全措施的啟用順序。只要開放 Webhook 測試,就要先做必要的驗簽、金鑰保護與存取限制;不能等到安全篇才補上。

其中,Evaluation——也就是評測——不會等到 Agent 做完才開始。我預計在 Day 3 先建立二十題初始案例,記錄不使用地方工具時,模型如何處理問題。後續增加工具、狀態與權限控制,再比較哪些地方改善、哪些地方反而退步。

測試集也不會全部拿來反覆調整 Prompt,然後用同一批題目宣稱成績很好。我會區分開發用案例與保留驗收案例,記錄模型、設定、資料版本與測試條件,讓結果的適用範圍可以被理解。

三十天的交付目標,我先定成:

一個可操作的 Agent、三項受控工具、一百筆評測案例,以及一個能讓其他開發者重現的開源版本。

同時,我會以邀請至少三位外部開發者試用為目標,記錄他們能否安裝、卡在哪裡,以及文件如何修改。邀請不等於完成採用,失敗也不能從報告裡消失。

一百題不是神奇門檻。真正重要的是,每題測什麼、預期行為怎麼判斷,以及沒有通過時能否說明原因。最終報告會分別呈現工具選擇、參數、資料依據、拒答、任務完成與成本延遲,而不是只給一個漂亮總分。

LOCAL 的公開開發位置:jarsing/local-service-agent-for-line。目前先提供中英文 README 與本文的合成驗收規格 docs/day01/handoff-timeout-001.json;Agent 程式、部署與評測結果將隨後續文章逐步加入。目前是設計版本,不是已完成的服務。

每篇文章,我都會盡量回答三件事:昨天的版本為什麼不夠、今天為什麼這樣改,以及我拿什麼證明改對了。

如果某項雲端能力不適合這個規模,或某個實驗不支持原來的想法,我也會把它寫下來。範例程式教人照做,設計理由和失敗紀錄,才讓讀者有機會把方法帶到別的專案。

結語:把「完成」這兩個字,重新寫得有份量

今天沒有神奇的 Agent 展示,也沒有成功率百分之九十九的成績單。

今天完成的是一個起點:LOCAL 要服務誰、哪些責任留在後端、第一版做到哪裡,以及如何判定它真的完成工作。

早年,我從電腦雜誌投稿與技術書翻譯接觸技術寫作,也曾寫過小說。這次重新開始長篇連載,我希望把寫作帶回工程現場:不是把程式說得像魔法,而是讓讀者看懂,它怎麼運作,又在哪裡必須停下來。

地方服務裡的一句「完成」,不應該只是模型剛好生成的兩個字,而應該有一段可以被查證的系統狀態。

接下來三十天,我們就從這裡開始。

下一篇:Day 2|誰需要 LOCAL?從使用者、服務情境到明確的非目標。


參考資料

[1] Google AI for Developers:Function calling with the Gemini API
[2] Google AI for Developers:Google AI Studio quickstart
[3] Google ADK:Conversational Context: Session, State, and Memory
[4] Google Developers Blog:Build with Google Antigravity, our new agentic development platform
[5] Google ADK:Deploy to Cloud Run
[6] Google AI for Developers:Structured outputs
[7] LINE Developers:Receive messages (webhook)


下一篇
Day 2|AI 說「完成」真的完成了嗎?把 LOCAL 的第一條驗收規格跑起來
系列文
LOCAL:30 天打造 LINE × Google AI 地方服務 Agent4
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言